package com.abo.yaas;

import java.util.Date;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ConcurrentHashMap;

import javax.persistence.EntityManager;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;

import com.abo.yaas.domain.Auction;
import com.abo.yaas.utils.EmailUtils;
import com.abo.yaas.webservice.hibernate.EMF;

@SuppressWarnings("serial")
public class AuctionResolverServlet extends HttpServlet {
    
    private static class AuctionResolveTask extends TimerTask {
        private final Auction auction;

        public AuctionResolveTask(final Auction auction) {
            this.auction = auction;
        }

        protected void doResolve() {
            if (auction == null) {
                return;
            }
            auction.resolve();
            saveAuction(auction);
            EmailUtils.sendAuctionresolvedEmail(auction);
        }

        private boolean endTimeUpdated(Auction auction) {
            final Date currentDate = new Date();
            final Date endTime = auction.getEndTime();
            if (Math.abs(currentDate.getTime() - endTime.getTime()) < 5000 * 60) {
                endTime.setTime(endTime.getTime() + 5000 * 60);
                auction.setEndTime(endTime);
                saveAuction(auction);
                return true;
            }
            return false;
        }

        @Override
        public void run() {
            doResolve();
        }

        protected void saveAuction(Auction auction) {
            final EntityManager em = EMF.get().createEntityManager();
            em.merge(auction);
            em.flush();
        }
    }

    private static Map<Object, AuctionResolveTask> jobMap = new ConcurrentHashMap<Object, AuctionResolveTask>();

    private static Timer timer = new Timer();

    public static void addAuctionTask(final Auction auction) {
        final AuctionResolveTask task = jobMap.get(auction.getId());
        if (task == null) {
            postTask(auction);
        } else if (task.endTimeUpdated(auction)) {
            task.cancel();
            jobMap.remove(task);
            postTask(auction);
        }
    }

    private static void postTask(final Auction auction) {
        final AuctionResolveTask task = new AuctionResolveTask(auction);
        jobMap.put(auction.getId(), task);
        timer.schedule(task, auction.getEndTime());
    }

    private static void resolveDelayed() {

    }

    @Override
    public void init() throws ServletException {
        super.init();
        resolveDelayed();
    }
}
